<template>
  <div class="org-container">
    <div class="toolbar">
      <el-input
        v-model="searchText"
        placeholder="搜索组织或人员"
        prefix-icon="el-icon-search"
        clearable
        @clear="clearSearch"
        style="width: 250px; margin-right: auto;"
      />
      <el-button type="primary" @click="expandAll">全部展开</el-button>
      <el-button type="primary" @click="collapseAll">全部收起</el-button>
      <el-button type="success" @click="addNode">添加节点</el-button>
      <el-button type="danger" @click="removeNode" :disabled="!selectedNode">删除节点</el-button>
    </div>
    
    <div class="org-chart-container">
      <el-tree
        ref="orgTree"
        :data="orgData"
        :props="defaultProps"
        :filter-node-method="filterNode"
        :expand-on-click-node="false"
        node-key="id"
        default-expand-all
        class="org-tree"
        @node-click="handleNodeClick"
      >
        <template #default="{ node, data }">
          <div class="custom-tree-node" :class="{ 'selected': selectedNode && selectedNode.id === data.id }">
            <div class="node-content">
              <div class="node-header">
                <span class="node-label">{{ data.label }}</span>
                <span class="node-title">{{ data.title }}</span>
              </div>
              <div class="node-actions">
                <el-button
                  type="text"
                  size="small"
                  @click.stop="editNode(data)"
                >
                  <i class="el-icon-edit"></i>
                </el-button>
                <el-button
                  v-if="hasChildren(data)"
                  type="text"
                  size="small"
                  @click.stop="toggleNode(node)"
                >
                  <i :class="node.expanded ? 'el-icon-minus' : 'el-icon-plus'"></i>
                </el-button>
              </div>
            </div>
          </div>
        </template>
      </el-tree>
    </div>
    
    <el-dialog v-model="dialogVisible" title="添加/编辑节点" width="30%">
      <el-form :model="nodeForm" label-width="80px">
        <el-form-item label="名称">
          <el-input v-model="nodeForm.name"></el-input>
        </el-form-item>
        <el-form-item label="职位">
          <el-input v-model="nodeForm.title"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveNode">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, nextTick, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'

// 组织架构数据
const orgData = ref([
  {
    id: 1,
    label: '总裁办',
    title: '公司总部',
    children: [
      {
        id: 2,
        label: '张三',
        title: '总裁',
        children: [
          {
            id: 3,
            label: '李四',
            title: '副总裁',
            children: [
              {
                id: 4,
                label: '研发部',
                title: '技术部门',
                children: [
                  { id: 5, label: '王五', title: '研发总监' },
                  { id: 6, label: '赵六', title: '高级工程师' }
                ]
              },
              {
                id: 7,
                label: '市场部',
                title: '市场部门',
                children: [
                  { id: 8, label: '钱七', title: '市场总监' }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
])

// 状态变量
const selectedNode = ref(null)
const dialogVisible = ref(false)
const nodeForm = reactive({
  id: null,
  name: '',
  title: '',
  parentId: null
})
const isEdit = ref(false)
const searchText = ref('')
const orgTree = ref(null)

// 树形控件配置
const defaultProps = {
  children: 'children',
  label: 'label'
}

// 检查节点是否有子节点
const hasChildren = (node) => {
  return node.children && node.children.length > 0
}

// 过滤节点方法
const filterNode = (value, data) => {
  if (!value) return true
  return data.label.includes(value) || data.title.includes(value)
}

// 监听搜索文本变化
watch(searchText, (val) => {
  orgTree.value.filter(val)
})

// 清除搜索
const clearSearch = () => {
  searchText.value = ''
}

// 处理节点点击
const handleNodeClick = (data) => {
  selectedNode.value = data
}

// 切换节点展开/折叠状态
const toggleNode = (node) => {
  node.expanded ? node.collapse() : node.expand()
}

// 展开所有节点
const expandAll = () => {
  orgTree.value.expandAll()
}

// 收起所有节点
const collapseAll = () => {
  orgTree.value.collapseAll()
}

// 添加节点
const addNode = () => {
  isEdit.value = false
  nodeForm.id = null
  nodeForm.name = ''
  nodeForm.title = ''
  nodeForm.parentId = selectedNode.value ? selectedNode.value.id : null
  dialogVisible.value = true
}

// 编辑节点
const editNode = (node) => {
  selectedNode.value = node
  isEdit.value = true
  nodeForm.id = node.id
  nodeForm.name = node.label
  nodeForm.title = node.title
  dialogVisible.value = true
}

// 保存节点
const saveNode = () => {
  if (!nodeForm.name) {
    ElMessage.warning('请输入节点名称')
    return
  }
  
  if (isEdit.value) {
    // 编辑现有节点
    updateNodeById(orgData.value, nodeForm.id, {
      label: nodeForm.name,
      title: nodeForm.title
    })
    ElMessage.success('节点更新成功')
  } else {
    // 添加新节点
    const newNode = {
      id: Date.now(), // 使用时间戳作为临时ID
      label: nodeForm.name,
      title: nodeForm.title,
      children: []
    }
    
    if (nodeForm.parentId) {
      // 添加到选中节点的子节点
      addChildToNode(orgData.value, nodeForm.parentId, newNode)
    } else {
      // 添加到根节点
      orgData.value.push(newNode)
    }
    ElMessage.success('节点添加成功')
  }
  
  dialogVisible.value = false
  
  // 更新树形控件
  nextTick(() => {
    if (searchText.value) {
      orgTree.value.filter(searchText.value)
    }
  })
}

// 删除节点
const removeNode = () => {
  if (!selectedNode.value) {
    ElMessage.warning('请先选择一个节点')
    return
  }
  
  ElMessageBox.confirm(
    `确定要删除节点 "${selectedNode.value.label}" 吗？`,
    '警告',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(() => {
    removeNodeById(orgData.value, selectedNode.value.id)
    selectedNode.value = null
    ElMessage.success('节点删除成功')
  }).catch(() => {})
}

// 根据ID更新节点
const updateNodeById = (nodes, id, newData) => {
  for (let i = 0; i < nodes.length; i++) {
    if (nodes[i].id === id) {
      Object.assign(nodes[i], newData)
      return true
    }
    if (nodes[i].children && nodes[i].children.length) {
      if (updateNodeById(nodes[i].children, id, newData)) {
        return true
      }
    }
  }
  return false
}

// 根据父节点ID添加子节点
const addChildToNode = (nodes, parentId, newNode) => {
  for (let i = 0; i < nodes.length; i++) {
    if (nodes[i].id === parentId) {
      if (!nodes[i].children) {
        nodes[i].children = []
      }
      nodes[i].children.push(newNode)
      return true
    }
    if (nodes[i].children && nodes[i].children.length) {
      if (addChildToNode(nodes[i].children, parentId, newNode)) {
        return true
      }
    }
  }
  return false
}

// 根据ID删除节点
const removeNodeById = (nodes, id) => {
  for (let i = 0; i < nodes.length; i++) {
    if (nodes[i].id === id) {
      nodes.splice(i, 1)
      return true
    }
    if (nodes[i].children && nodes[i].children.length) {
      if (removeNodeById(nodes[i].children, id)) {
        return true
      }
    }
  }
  return false
}
</script>

<style scoped>
.org-container {
  padding: 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.toolbar {
  margin-bottom: 20px;
  display: flex;
  gap: 10px;
  align-items: center;
}

.org-chart-container {
  flex: 1;
  overflow: auto;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 20px;
  background-color: #f5f7fa;
}

/* 自定义树形控件样式 */
.org-tree {
  background: transparent;
  color: #303133;
}

:deep(.el-tree-node__content) {
  height: auto;
  padding: 10px 0;
}

:deep(.el-tree-node__expand-icon) {
  font-size: 16px;
  padding: 6px;
}

.custom-tree-node {
  width: 100%;
  padding: 15px;
  border: 1px solid #dcdfe6;
  border-radius: 8px;
  background-color: #fff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
}

.custom-tree-node:hover {
  transform: translateY(-3px);
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}

.custom-tree-node.selected {
  border-color: #409eff;
  background-color: #ecf5ff;
}

.node-content {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.node-header {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.node-label {
  font-weight: bold;
  font-size: 16px;
  color: #303133;
}

.node-title {
  color: #606266;
  font-size: 14px;
}

.node-actions {
  display: flex;
  justify-content: flex-end;
  gap: 5px;
  margin-top: 8px;
}

:deep(.el-tree-node__children) {
  padding-left: 30px;
  position: relative;
}

:deep(.el-tree-node__children::before) {
  content: '';
  position: absolute;
  left: 10px;
  top: 0;
  bottom: 0;
  width: 2px;
  background-color: #dcdfe6;
}

:deep(.el-tree-node:last-child > .el-tree-node__children::before) {
  bottom: auto;
  height: 20px;
}
</style>
